//promise example
#include <iostream>       // std::cout
#include <functional>     // std::ref
#include <thread>         // std::thread
#include <future>         // std::promise, std::future
#include <chrono>

using namespace std;

void print_int (future<int>& fut) {
    int x = fut.get();
    cout << "value: " << x << '\n';
}

void task1(promise<int>& param)
{
    const int second = 5;
    cout << "task1 sleeping for " << second << endl;
    this_thread::sleep_for(chrono::seconds(second));

    const int val = 22;
    param.set_value(val);
    cout << "task1 set promise " << val << endl;
}

void task2(promise<int>& param)
{
    const int second = 1;
    cout << "task2 sleeping for " << second << endl;
    this_thread::sleep_for(chrono::seconds(second));

    const int val = 11;
    param.set_value(val);
    cout << "task2 set promise " << val << endl;
}

int main ()
{
    promise<int> prom1;
    promise<int> prom2;

    thread th1 (task1, std::ref(prom1));
    thread th2 (task2, std::ref(prom2));

    cout<<"get results:"<<endl;

    // future act like unique_ptr
    // shared_future act like shared_ptr
    future<int> fut1 = prom1.get_future();
    future<int> fut2 = prom2.get_future();

    if (fut1.wait_for(chrono::seconds(2)) == future_status::timeout )
            cout<<"task1 timeout"<<endl;
    fut2.wait();

    cout<<"task1:" <<fut1.get()<<endl;
    cout<<"task2:" <<fut2.get()<<endl;
    
    th1.join();
    th2.join();
    return 0;
}







